package utils;

import structure.ListenerNode;
import structure.Transcation;
import structure.TranscationRoute;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

public class ProcessUtils {
    //private static final String filepath = "D:\\project\\vibes\\log\\logfile";
    private static final String outputpath="D:\\project\\";
    public static final int X=3;
    public static File openFile(String filepath,String fileData) {
        try {
            File file = new File(filepath + fileData + ".log");
            if (file.isFile() && file.exists()) { //判断文件是否存
                return file;
            } else {
                System.out.println("找不到指定的文件");
                return null;
            }
        } catch (Exception e) {
            System.out.println("读取文件内容出错");
            e.printStackTrace();
            return null;
        }
    }

    public static String[] delElement(String[] arrays, int index) {
        int length = arrays.length;
        //判断数据合理性
        if (index >= 0 && index < length) {
            String[] arrays_result = new String[arrays.length - 1];
            //将arrays数组在index前的元素都复制到新数组arrays_result中
            System.arraycopy(arrays, 0, arrays_result, 0, index);
            //判断index之后是否还有元素，有则将index后的元素从index位置复制到新数组中
            if (index < length - 1) {
                System.arraycopy(arrays, index + 1, arrays_result, index, arrays_result.length - index);
            }
            return arrays_result;
        } else {
            //不合理，抛越界异常
            throw new IndexOutOfBoundsException("index :" + index + ", length: " + length);
        }
    }


    /**
     * 仿真环境下
     * 读取日志文件file，拆分数据到listenerNodeMap，transactionMap，normalNodeSet
     */
    public static void processDataToMapAndSet_Simulation(File file, HashMap<String, ListenerNode> listenerNodeMap, HashMap<String, Transcation> transactionMap, HashSet<String> normalNodeSet) {

        TranscationReader sf;
        try {
            //读取文件
            assert file != null;
            sf = new TranscationReader(new BufferedReader(new FileReader(file)));
            String[] line = sf.readTx();
            while (line != null) {//这里line存放的是每一行的数据，存成了数组
                switch (line[0]) {
                    case "trans_create":
                        transactionMap.put(line[3],new Transcation(line[1],line[2],line[3])); //记录产生的交易（这个应该不会重，就没检查）
                        break;
                    case "listen_tx":
                        TranscationRoute route= new TranscationRoute(line[1],line[2],line[4]); //首先创建一个交易路径
                        ListenerNode superListener = listenerNodeMap.get("superListener");
                        superListener.neightourHas.add(line[2]);
                        superListener.txListenSet.add(route);
                        if (!listenerNodeMap.containsKey(line[3])) {
                            ListenerNode listenerNode =new ListenerNode(line[3], new HashSet<>(), new ArrayList<>());
                            listenerNode.neightourHas.add(line[2]);//更新监听节点的历史邻居列表
                            listenerNode.txListenSet.add(route);//更新监听节点的监听route列表
                            listenerNodeMap.put(line[3],listenerNode);
                        }else{ //监听节点已经存在于map里了
                            ListenerNode listenernode=listenerNodeMap.get(line[3]); //拿到这个监听节点，然后修改里面的东西
                            listenernode.neightourHas.add(line[2]);//更新监听节点的历史邻居列表
                            listenernode.txListenSet.add(route);//更新监听节点的监听route列表
                        }
                        break;
                    case "node_info":
                        //if (line[2].equals("Some(false)")) {
                            normalNodeSet.add(line[1]);
                       // }
                        break;
                }
                line = sf.readTx();
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
            System.exit(-1);
        }
    }



    /**
     * 测试网环境中，读取日志文件file，拆分数据到listenerNodeMap，transactionMap，normalNodeSet
     * @param file 输入文件对像
     * @param transactionMap 交易存放的Map
     * @param normalNodeSet  节点存放的Set
     */
    public static void processDataToMapAndSet_Testnet(File file, HashMap<String, Transcation> transactionMap, HashSet<String> normalNodeSet) {
        TranscationReader sf;
        try {
            //读取文件
            assert file != null;
            sf = new TranscationReader(new BufferedReader(new FileReader(file)));
            String[] line = sf.readTx();
            while (line != null) {//这里line存放的是每一行的数据，存成了数组
                switch (line[0]) {
                    case "r:itx":
                        TranscationRoute route= new TranscationRoute(line[1],line[2],line[4]); //首先创建一个交易路径
                        ListenerNode superListener = listenerNodeMap.get("superListener");
                        superListener.neightourHas.add(line[2]);
                        superListener.txListenSet.add(route);
                        if (!listenerNodeMap.containsKey(line[3])) {
                            ListenerNode listenerNode =new ListenerNode(line[3], new HashSet<>(), new ArrayList<>());
                            listenerNode.neightourHas.add(line[2]);//更新监听节点的历史邻居列表
                            listenerNode.txListenSet.add(route);//更新监听节点的监听route列表
                            listenerNodeMap.put(line[3],listenerNode);
                        }else{ //监听节点已经存在于map里了
                            ListenerNode listenernode=listenerNodeMap.get(line[3]); //拿到这个监听节点，然后修改里面的东西
                            listenernode.neightourHas.add(line[2]);//更新监听节点的历史邻居列表
                            listenernode.txListenSet.add(route);//更新监听节点的监听route列表
                        }
                        break;
                    case "r:addr":
                        //if (line[2].equals("Some(false)")) {
                        normalNodeSet.add(line[1]);
                        // }
                        break;
                }
                line = sf.readTx();
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
            System.exit(-1);
        }
    }

    public static int findElement(String[] objects,String obj){
        for (int i = 0; i <objects.length; i++) {
            if(objects[i].equals(obj)){
                return i;
            }
        }
        return -1;
    }
}
